﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using UmlControlLibrary;

namespace UmlControlLibrary
{
    public class UmlModel : UmlElement
    {
        public override ObservableCollection<UmlElement> GetChilds()
        {
            ObservableCollection<UmlElement> res = new ObservableCollection<UmlElement>();
            foreach (UmlElement element in Packages.Elements)
                res.Add(element);
            foreach (UmlElement element in Diagrams.Elements)
                res.Add(element);
            return res;
        }

        public void MergePackages(IEnumerable<UmlElement> elements)
        {
            foreach (UmlElement e in elements)
            {
                if (e is UmlPackage)
                {
                    UmlPackage p = Packages.GetElementByName(e.Name);
                    if (p != null)
                    {
                        p.MergePackage((UmlPackage)e);
                        p.Sort();
                    }
                    else
                    {
                        Packages.AddElement((UmlPackage)e);
                        ((UmlPackage)e).Sort();
                    }
                }
                else
                {
                    CurrentPackage.AddElement(e);
                }
            }
         //   CurrentPackage.Sort();
        }

        // We can have only one model loaded
        private static UmlModel _instance = null;
        public static UmlModel GetInstance()
        {
            if (_instance == null)
            {
                _instance = new UmlModel();
                _instance.Packages.AddElement(UmlPackage.CreateBuiltinSystemPackage());
            }
            return _instance;
        }

        /// <summary>
        /// Model diagrams
        /// </summary>
        private UmlModelElementList<UmlDiagram> _diagrams = new UmlModelElementList<UmlDiagram>();
        public UmlModelElementList<UmlDiagram> Diagrams
        {
            get { return _diagrams; }
        }

        /// <summary>
        /// Model package
        /// </summary>
        private UmlModelElementList<UmlPackage> _packages = new UmlModelElementList<UmlPackage>();
        public UmlModelElementList<UmlPackage> Packages
        {
            get { return _packages; }
        }

        /// <summary>
        /// All model elements. All.
        /// </summary>
        private UmlModelElementList<UmlElement> _allElements = new UmlModelElementList<UmlElement>();
        public UmlModelElementList<UmlElement> AllElements
        {
            get { return _allElements; }
        }

        // Helper functions

        public static bool AddElement(UmlElement element)
        {
            return GetInstance().AllElements.AddElement(element);
        }

        public static UmlDiagram CurrentDiagram
        {
            get { return UmlModel.GetInstance().Diagrams.Current; }
        }

        public static UmlPackage CurrentPackage
        {
            get { return UmlModel.GetInstance().Packages.Current; }
        }

        private static int UmlElementNameComparer(UmlElement e1, UmlElement e2)
        {
            return e1.Name.CompareTo(e2.Name);
        }
        public static List<UmlElement> GetTypesList()
        {
            List<UmlElement> result = new List<UmlElement>();
            //result.Add("String");
            //result.Add("Int");

            foreach (UmlElement c in GetInstance().AllElements.Elements)
                result.Add(c);

            result.Sort(UmlElementNameComparer);
            
            return result;
        }
    }
}
